//Test case Description:
//This testcase Performs writing data into the Particular sector of the Flash memory. 

`define QUADSPI_CR 		32'h00000000
`define QUADSPI_DCR 	32'h00000004
`define QUADSPI_SR		32'h00000008
`define QUADSPI_FCR 	32'h0000000c
`define QUADSPI_DLR		32'h00000010
`define QUADSPI_CCR 	32'h00000014
`define QUADSPI_AR		32'h00000018
`define QUADSPI_ABR		32'h0000001c
`define QUADSPI_DR		32'h00000020
`define QUADSPI_PSMKR	32'h00000024
`define QUADSPI_PSMAR	32'h00000028
`define QUADSPI_PIR		32'h0000002c
`define QUADSPI_LPTR	32'h00000030

class pageProgram_2 extends axi_master_base_test;
    
  `uvm_component_utils(pageProgram_2)
  
  //---------------------------------------
  // sequence instance 
  ////-------------------------------------
  
  axi_master_write_seq wseq;
  axi_master_read_seq rseq;

  //---------------------------------------
  // constructor
  //---------------------------------------
  function new(string name = "pageProgram_2",uvm_component parent=null);
    super.new(name,parent);
  endfunction : new

  //---------------------------------------
  // build_phase
  //---------------------------------------
  virtual function void build_phase(uvm_phase phase);    
    super.build_phase(phase);

    // Create the sequence
    
    wseq = axi_master_write_seq::type_id::create("wseq");
    rseq = axi_master_read_seq::type_id::create("rseq");
		
  endfunction : build_phase
  
  //---------------------------------------
  // run_phase - starting the test
  //---------------------------------------
  task run_phase(uvm_phase phase);
    
    phase.raise_objection(this);    
    wseq.length  = 4'b0000;
    wseq.awid    = 4'b0001;
    //wseq.wid     = 4'b0001;		  
	rseq.length  = 4'b0000;
    rseq.arid    = 4'b0001; 
	    
	//Enabling the QSPI Controller	
	// sending address and data to QUADSPI_CR
	wseq.waddr   = `QUADSPI_CR; 
	wseq.wdata   = 32'h031f0f01; // Enable QSPI 25 MHz
	wseq.wdata_v = 1;
	#10; 
	wseq.wdata_v = 0;
    wseq.start(env.axi_agnt.sequencer);
    // sending data to QUADSPI_DCR
	wseq.waddr   = `QUADSPI_DCR; 
	wseq.wdata   = 32'h001b0001; 
	wseq.wdata_v = 1;
	#10;
	wseq.wdata_v = 0;
    wseq.start(env.axi_agnt.sequencer);
         
    wait(axi_master_tb_top_qspi.flash_inst.flash.Chip_EN);
 	 
    //---------------------------------------
    // Writing into Flash
    //---------------------------------------
		
	// sending data to QUADSPI_CCR
	wseq.waddr   = `QUADSPI_CCR;
	wseq.wdata   = 32'h00003106;  // Write Enable 
	wseq.wdata_v = 1;
	#10;
	wseq.wdata_v = 0;
    wseq.start(env.axi_agnt.sequencer);

	wait(axi_master_tb_top_qspi.qspi_inst.qspi_sr_tcf);
	   	
	// sending data to QUADSPI_FCR
	wseq.waddr   = `QUADSPI_FCR; 
	wseq.wdata   = 32'h0000001b; // Flag Clear Register
	wseq.wdata_v = 1;
	#10;
	wseq.wdata_v = 0;
    wseq.start(env.axi_agnt.sequencer);

    wait(!(axi_master_tb_top_qspi.flash_inst.flash.WIP)); 
	    
	// sending data to QUADSPI_DLR
	wseq.waddr   = `QUADSPI_DLR; 
	wseq.wdata   =  32'h0000000F; //16 bytes 
	wseq.wdata_v = 1;
	#10;
	wseq.wdata_v = 0;
    wseq.start(env.axi_agnt.sequencer);		
		
	// sending data to QUADSPI_CCR
	wseq.waddr   = `QUADSPI_CCR;
	wseq.wdata   = 32'h01003512;  // writing data into flash in SPI mode. after this 12h instruction "WIP" signal should go high. 
	                              // But it is not happening in this scenario and the "STATE" signal of FLASh going BAD_CMD_STATE.
								  // this is the reason we are unable to write data to flash.
	wseq.wdata_v = 1;
	#10;
	wseq.wdata_v = 0;
    wseq.start(env.axi_agnt.sequencer);			
	   
	// sending data to QUADSPI_AR
	wseq.waddr   = `QUADSPI_AR;   
    wseq.wdata   = 32'h00010000; // Writing Address
	wseq.wdata_v = 1;
	#10;
	wseq.wdata_v = 0;
    wseq.start(env.axi_agnt.sequencer);
	
	//Writing 16 bytes data into flash.Configuring Data Register 4 times.  
	
	// sending data to QUADSPI_DR_1
	wseq.waddr   = `QUADSPI_DR; 
    wseq.wdata   = 32'hff00ff00;  
	wseq.wdata_v = 1;
	#10;
	wseq.wdata_v = 0;
    wseq.start(env.axi_agnt.sequencer);	

	// sending data to QUADSPI_DR_2
	wseq.waddr   = `QUADSPI_DR;
	wseq.wdata   = 32'hff00ff00;   
	wseq.wdata_v = 1;
	#10;
	wseq.wdata_v = 0;
    wseq.start(env.axi_agnt.sequencer);
	   
	// sending data to QUADSPI_DR_3
	wseq.waddr   = `QUADSPI_DR;
	wseq.wdata   = 32'hff00ff00;    
	wseq.wdata_v = 1;
	#10;
	wseq.wdata_v = 0;
    wseq.start(env.axi_agnt.sequencer);
    
    // sending data to QUADSPI_DR_4
	wseq.waddr   = `QUADSPI_DR;
	wseq.wdata   = 32'hff00ff00;    
	wseq.wdata_v = 1;
	#10;
	wseq.wdata_v = 0;
    wseq.start(env.axi_agnt.sequencer);	   
	
    wait(axi_master_tb_top_qspi.qspi_inst.qspi_sr_tcf);
		  
	// sending data to QUADSPI_FCR
	wseq.waddr   = `QUADSPI_FCR; 
	wseq.wdata   = 32'h0000001b; // Flag Clear Register
	wseq.wdata_v = 1;
	#10;
	wseq.wdata_v = 0;
    wseq.start(env.axi_agnt.sequencer);		
    
    $display("Writing to Flash test case completed");	
        
    phase.drop_objection(this);
	
    //set a drain-time for the environment if desired
    phase.phase_done.set_drain_time(this, 100);
    
  endtask : run_phase

endclass : pageProgram_2
